﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Practices.ServiceLocation;
using Pap.Core.Utilities;
using Pap.Data;
using Pap.Data.Abstraction.Utils;
using Pap.Services;
using Pap.Services.WorkflowEngine;
using Pap.Web.Utils;

namespace Pap.Web.Modules.Loan.ViewModel
{
    /// <summary>
    /// 
    /// </summary>
    public class NewLoanListViewModel : IViewModel
    {
        #region  [ Fields ]
        /// <summary>
        /// 
        /// </summary>
        private readonly IWorkflowService _wfServise;
        /// <summary>
        /// 
        /// </summary>
        private readonly ILoanRepository _loanRepository;
        /// <summary>
        /// 
        /// </summary>
        private readonly IResponsibleService _responsibleService;
        /// <summary>
        /// 
        /// </summary>
        private readonly ILoanExecutionService _loanExecutionService;
        #endregion

        #region [ Constructor ]

        /// <summary>
        /// Initializes a new instance of the <see cref="NewLoanListViewModel"/> class.
        /// </summary>
        /// <param name="wfServise">The wf servise.</param>
        /// <param name="loanRepository">The loan repository.</param>
        /// <param name="responsibleService">The responsible service.</param>
        /// <param name="loanExecutionService">The loan execution service.</param>
        public NewLoanListViewModel(IWorkflowService wfServise, ILoanRepository loanRepository,
            IResponsibleService responsibleService, ILoanExecutionService loanExecutionService)
        {
            _wfServise = wfServise;
            _loanRepository = loanRepository;
            _responsibleService = responsibleService;
            _loanExecutionService = loanExecutionService;
        }
        #endregion
        /// <summary>
        /// Gets list of all new loans.
        /// </summary>
        /// <returns></returns>
        public IEnumerable<ICustomerLoan> GetNewLoans()
        {
            var allLoans = _loanRepository.FindCustomerLoans(loan => true);

            return (from loan in allLoans
                    where _wfServise.GetProcessInstanceByEntity(loan.LoanID) == null
                    orderby loan.LoanNumber ascending
                    select loan);
        }

        /// <summary>
        /// Submits the loans to create processinstance for it and but it at the first step at loan cycle.
        /// </summary>
        /// <param name="loanData">The loan data.</param>
        public void SubmitLoans(Dictionary<Guid, string> loanData)
        {
            using (var transaction = ServiceLocator.Current.GetInstance<IUnitOfWork>())
            {
                foreach (var loan in loanData)
                {
                    ICustomerLoan tempLoan = _loanRepository.GetCustomerLoanByID(loan.Key);
                    tempLoan.ResponsibleID = _responsibleService.GetFreeResponsibleID(RegistryInfo.CommitteeID, tempLoan.ProjectStage.ProjectObj);
                    _wfServise.CreateProcessInstance(Process.LoanCycle, loan.Key, RegistryInfo.UserID, loan.Value);

                    // if the customer is crantor for another project and payed less than 0.75
                    if (!_loanExecutionService.ValidateGurantorWarning(tempLoan.CustomerObj.SSN))
                    {
                        var processInstance = _wfServise.GetProcessInstanceByEntity(loan.Value.ToGuid());
                        _wfServise.Move(ActionTypes.Freeze, processInstance.ProcessInstanceID, RegistryInfo.UserID,
                                        string.Empty,
                                        DateTime.Now);
                    }
                }
                transaction.Commit();
            }
        }

        /// <summary>
        /// Deletes all loans.
        /// </summary>
        /// <param name="selectedLoans">The selected loans.</param>
        public void DeleteAllLoans(List<Guid> selectedLoans)
        {
            using (var transaction = ServiceLocator.Current.GetInstance<IUnitOfWork>())
            {
                foreach (var loanId in selectedLoans)
                {
                    var loan = _loanRepository.GetCustomerLoanByID(loanId);
                    if (loan.CustomerObj.Loans.Count() < 2)
                    {
                        _loanRepository.DeleteCustomer(loan.CustomerObj);
                    }
                    _loanRepository.DeleteCustomerLoan(loan);
                }
                transaction.Commit();
            }
        }
    }
}
